package com.example.managemyself.api.service;

import com.example.managemyself.api.entity.Task;
import com.example.managemyself.api.repository.TaskRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 任务服务类
 */
@Service
@Transactional
public class TaskService {
    
    @Autowired
    private TaskRepository taskRepository;
    
    /**
     * 创建新任务
     */
    public Task createTask(Task task) {
        // 设置默认值
        if (task.getStatus() == null) {
            task.setStatus(Task.TaskStatus.TODO);
        }
        if (task.getPriority() == null) {
            task.setPriority(Task.Priority.MEDIUM);
        }
        
        return taskRepository.save(task);
    }
    
    /**
     * 根据ID获取任务
     */
    public Optional<Task> getTaskById(Long id) {
        return taskRepository.findById(id);
    }
    
    /**
     * 更新任务
     */
    public Task updateTask(Long id, Task taskDetails) {
        Task task = taskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        // 更新任务信息
        if (taskDetails.getTitle() != null) {
            task.setTitle(taskDetails.getTitle());
        }
        if (taskDetails.getDescription() != null) {
            task.setDescription(taskDetails.getDescription());
        }
        if (taskDetails.getStatus() != null) {
            task.setStatus(taskDetails.getStatus());
        }
        if (taskDetails.getPriority() != null) {
            task.setPriority(taskDetails.getPriority());
        }
        if (taskDetails.getDueDate() != null) {
            task.setDueDate(taskDetails.getDueDate());
        }
        if (taskDetails.getTags() != null) {
            task.setTags(taskDetails.getTags());
        }
        if (taskDetails.getEstimatedHours() != null) {
            task.setEstimatedHours(taskDetails.getEstimatedHours());
        }
        if (taskDetails.getActualHours() != null) {
            task.setActualHours(taskDetails.getActualHours());
        }
        
        return taskRepository.save(task);
    }
    
    /**
     * 删除任务
     */
    public void deleteTask(Long id) {
        if (!taskRepository.existsById(id)) {
            throw new RuntimeException("任务不存在: " + id);
        }
        taskRepository.deleteById(id);
    }
    
    /**
     * 完成任务
     */
    public Task completeTask(Long id) {
        Task task = taskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        task.markAsCompleted();
        return taskRepository.save(task);
    }
    
    /**
     * 更新任务状态
     */
    public Task updateTaskStatus(Long id, Task.TaskStatus status) {
        Task task = taskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        task.setStatus(status);
        return taskRepository.save(task);
    }
    
    /**
     * 获取用户的所有任务
     */
    public List<Task> getUserTasks(Long userId) {
        return taskRepository.findByUserId(userId);
    }
    
    /**
     * 分页获取用户任务
     */
    public Page<Task> getUserTasks(Long userId, Pageable pageable) {
        return taskRepository.findByUserId(userId, pageable);
    }
    
    /**
     * 根据状态获取用户任务
     */
    public List<Task> getUserTasksByStatus(Long userId, Task.TaskStatus status) {
        return taskRepository.findByUserIdAndStatus(userId, status);
    }
    
    /**
     * 分页根据状态获取用户任务
     */
    public Page<Task> getUserTasksByStatus(Long userId, Task.TaskStatus status, Pageable pageable) {
        return taskRepository.findByUserIdAndStatus(userId, status, pageable);
    }
    
    /**
     * 根据优先级获取用户任务
     */
    public List<Task> getUserTasksByPriority(Long userId, Task.Priority priority) {
        return taskRepository.findByUserIdAndPriority(userId, priority);
    }
    
    /**
     * 获取用户的逾期任务
     */
    public List<Task> getUserOverdueTasks(Long userId) {
        return taskRepository.findOverdueTasksByUserId(userId, LocalDateTime.now(), Task.TaskStatus.COMPLETED);
    }
    
    /**
     * 获取用户今日到期的任务
     */
    public List<Task> getUserTasksDueToday(Long userId) {
        return taskRepository.findTasksDueToday(userId, LocalDateTime.now(), Task.TaskStatus.COMPLETED);
    }
    
    /**
     * 获取用户本周到期的任务
     */
    public List<Task> getUserTasksDueThisWeek(Long userId) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime weekStart = now.truncatedTo(ChronoUnit.DAYS);
        LocalDateTime weekEnd = weekStart.plusDays(7);
        
        return taskRepository.findTasksDueThisWeek(userId, weekStart, weekEnd, Task.TaskStatus.COMPLETED);
    }
    
    /**
     * 搜索用户任务
     */
    public Page<Task> searchUserTasks(Long userId, String keyword, Pageable pageable) {
        return taskRepository.searchTasksByUser(userId, keyword, pageable);
    }
    
    /**
     * 根据标签查找任务
     */
    public List<Task> getUserTasksByTag(Long userId, String tag) {
        return taskRepository.findTasksByTag(userId, tag);
    }
    
    /**
     * 批量更新任务状态
     */
    public void updateTasksStatus(List<Long> taskIds, Task.TaskStatus status) {
        taskRepository.updateTaskStatus(taskIds, status);
    }
    
    /**
     * 批量删除任务
     */
    public void deleteTasks(List<Long> taskIds) {
        taskRepository.deleteAllById(taskIds);
    }
    
    /**
     * 获取用户任务统计信息
     */
    public TaskStats getUserTaskStats(Long userId) {
        List<Object[]> statusStats = taskRepository.countTasksByStatus(userId);
        List<Object[]> priorityStats = taskRepository.countTasksByPriority(userId);
        
        TaskStats stats = new TaskStats();
        stats.setUserId(userId);
        stats.setTotalTasks(taskRepository.findByUserId(userId).size());
        
        // 统计各状态任务数量
        for (Object[] row : statusStats) {
            Task.TaskStatus status = (Task.TaskStatus) row[0];
            Long count = (Long) row[1];
            switch (status) {
                case TODO:
                    stats.setTodoCount(count);
                    break;
                case IN_PROGRESS:
                    stats.setInProgressCount(count);
                    break;
                case COMPLETED:
                    stats.setCompletedCount(count);
                    break;
                case CANCELLED:
                    stats.setCancelledCount(count);
                    break;
            }
        }
        
        // 统计各优先级任务数量
        for (Object[] row : priorityStats) {
            Task.Priority priority = (Task.Priority) row[0];
            Long count = (Long) row[1];
            switch (priority) {
                case LOW:
                    stats.setLowPriorityCount(count);
                    break;
                case MEDIUM:
                    stats.setMediumPriorityCount(count);
                    break;
                case HIGH:
                    stats.setHighPriorityCount(count);
                    break;
                case URGENT:
                    stats.setUrgentPriorityCount(count);
                    break;
            }
        }
        
        // 计算完成率
        Double completionRate = taskRepository.getTaskCompletionRate(userId, Task.TaskStatus.COMPLETED);
        stats.setCompletionRate(completionRate != null ? completionRate : 0.0);
        
        // 统计逾期任务数量
        stats.setOverdueCount((long) getUserOverdueTasks(userId).size());
        
        // 统计高优先级未完成任务数量
        List<Task.Priority> highPriorities = Arrays.asList(Task.Priority.HIGH, Task.Priority.URGENT);
        Long highPriorityIncomplete = taskRepository.countHighPriorityIncompleteTasks(userId, highPriorities, Task.TaskStatus.COMPLETED);
        stats.setHighPriorityIncompleteCount(highPriorityIncomplete != null ? highPriorityIncomplete : 0L);
        
        return stats;
    }
    
    /**
     * 获取任务完成统计（按日期）
     */
    public List<Object[]> getTaskCompletionStats(Long userId, LocalDateTime startDate) {
        return taskRepository.getTaskCompletionStats(userId, startDate);
    }
    
    /**
     * 获取用户在指定时间范围内创建的任务
     */
    public List<Task> getTasksCreatedBetween(Long userId, LocalDateTime startDate, LocalDateTime endDate) {
        return taskRepository.findTasksCreatedBetween(userId, startDate, endDate);
    }
    
    /**
     * 获取用户在指定时间范围内完成的任务
     */
    public List<Task> getTasksCompletedBetween(Long userId, LocalDateTime startDate, LocalDateTime endDate) {
        return taskRepository.findTasksCompletedBetween(userId, startDate, endDate);
    }
    
    /**
     * 清理已取消的旧任务
     */
    public void cleanupOldCancelledTasks(int daysOld) {
        LocalDateTime cutoffDate = LocalDateTime.now().minusDays(daysOld);
        taskRepository.deleteOldCancelledTasks(Task.TaskStatus.CANCELLED, cutoffDate);
    }
    
    /**
     * 任务统计信息类
     */
    public static class TaskStats {
        private Long userId;
        private Integer totalTasks = 0;
        private Long todoCount = 0L;
        private Long inProgressCount = 0L;
        private Long completedCount = 0L;
        private Long cancelledCount = 0L;
        private Long lowPriorityCount = 0L;
        private Long mediumPriorityCount = 0L;
        private Long highPriorityCount = 0L;
        private Long urgentPriorityCount = 0L;
        private Double completionRate = 0.0;
        private Long overdueCount = 0L;
        private Long highPriorityIncompleteCount = 0L;
        
        // Getters and Setters
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public Integer getTotalTasks() { return totalTasks; }
        public void setTotalTasks(Integer totalTasks) { this.totalTasks = totalTasks; }
        
        public Long getTodoCount() { return todoCount; }
        public void setTodoCount(Long todoCount) { this.todoCount = todoCount; }
        
        public Long getInProgressCount() { return inProgressCount; }
        public void setInProgressCount(Long inProgressCount) { this.inProgressCount = inProgressCount; }
        
        public Long getCompletedCount() { return completedCount; }
        public void setCompletedCount(Long completedCount) { this.completedCount = completedCount; }
        
        public Long getCancelledCount() { return cancelledCount; }
        public void setCancelledCount(Long cancelledCount) { this.cancelledCount = cancelledCount; }
        
        public Long getLowPriorityCount() { return lowPriorityCount; }
        public void setLowPriorityCount(Long lowPriorityCount) { this.lowPriorityCount = lowPriorityCount; }
        
        public Long getMediumPriorityCount() { return mediumPriorityCount; }
        public void setMediumPriorityCount(Long mediumPriorityCount) { this.mediumPriorityCount = mediumPriorityCount; }
        
        public Long getHighPriorityCount() { return highPriorityCount; }
        public void setHighPriorityCount(Long highPriorityCount) { this.highPriorityCount = highPriorityCount; }
        
        public Long getUrgentPriorityCount() { return urgentPriorityCount; }
        public void setUrgentPriorityCount(Long urgentPriorityCount) { this.urgentPriorityCount = urgentPriorityCount; }
        
        public Double getCompletionRate() { return completionRate; }
        public void setCompletionRate(Double completionRate) { this.completionRate = completionRate; }
        
        public Long getOverdueCount() { return overdueCount; }
        public void setOverdueCount(Long overdueCount) { this.overdueCount = overdueCount; }
        
        public Long getHighPriorityIncompleteCount() { return highPriorityIncompleteCount; }
        public void setHighPriorityIncompleteCount(Long highPriorityIncompleteCount) { this.highPriorityIncompleteCount = highPriorityIncompleteCount; }
    }
} 